let astNodeTags = require('../common/ast-node-tags');
let commandModule = require('../modules/command-module');
let commandUtil = require('./command-util');
let nodeUtil = require('../common/node-util');

let expCmdGenerator = {
  result: {},
  generate(node) {
    if (node.tag == astNodeTags.ASSIGN) {
      this.result = this.genAssignCommand(node);
    } else {
      if (!nodeUtil.isNodeLiteral(node.right) && node.right.left.tag == astNodeTags.URI) {
        this.result = this.genCreateCommand(node);
      } else {
        this.result = this.genConnectCommand(node);
      }
    }
    return this.result;
  },
  genAssignCommand(node) {
    let target = nodeUtil.getLiteralValue(node.left.left);
    let scope = commandUtil.getAssignScope(node);
    let key = nodeUtil.getLiteralValue(node.left.right);
    let value = nodeUtil.getLiteralValue(node.right);
    return new commandModule.Assign(target, scope, key, value);
  },
  genCreateCommand(node) {
    let uri = nodeUtil.getLiteralValue(node.right.left);
    let source, sp;
    if (nodeUtil.isNodeLiteral(node.left)) {
      // 源为开始节点
      source = nodeUtil.getLiteralValue(node.left);
    } else {
      source = nodeUtil.getLiteralValue(node.left.left);
      sp = nodeUtil.getLiteralValue(node.left.right);
    }
    let operaValue = node.right.operator.value;
    let refValue = nodeUtil.getLiteralValue(node.right.right);
    let pos = commandUtil.parsePosNode(operaValue, refValue);
    return new commandModule.Create(uri, source, sp, pos);
  },
  genConnectCommand(node) {
    let source, sp, target, tp;
    if (nodeUtil.isNodeLiteral(node.left)) {
      // 源为开始节点
      source = nodeUtil.getLiteralValue(node.left);
      target = nodeUtil.getLiteralValue(node.right);
    } else if (!nodeUtil.isNodeLiteral(node.right)) {
      // 目标为结束节点
      source = nodeUtil.getLiteralValue(node.left.left);
      sp = nodeUtil.getLiteralValue(node.left.right);
      target = nodeUtil.getLiteralValue(node.right.left);
      tp = nodeUtil.getLiteralValue(node.right.right);
    } else {
      source = nodeUtil.getLiteralValue(node.left.left);
      sp = nodeUtil.getLiteralValue(node.left.right);
      target = nodeUtil.getLiteralValue(node.right);
    }
    return new commandModule.Connect(source, sp, target, tp);
  }
};

module.exports = expCmdGenerator;
